local ActorBase = require("gameLogic.fight.ActorBase")
local FightActor = class("FightActor", ActorBase)
local GameUtils = require("utils.GameUtils")
local Vector3 = require("utils.Vector3")

function FightActor:ctor(config, manager, id)
    local object = G_ResourceManager:loadActor(config.res_name)
    FightActor.super.ctor(self, manager, id, object)
    self._bloodUI = require("gameLogic.ui.BloodUI").new(self)
    self._buffs = {}
    self._sheilds = {}
    self._dieAnim = false
    self._diePercent = 0
end

function FightActor:setName(name)
    self._bloodUI:setName(name .. "_" .. self._id)
end

function FightActor:getDebugName()
    return self._debugName
end

function FightActor:setElement(element)
    self._bloodUI:setElement(element)
end

function FightActor:start()
    self._animator = self.gameObject:GetComponent(typeof(Unity.Animator))
    self._renders = self.gameObject:GetComponentsInChildren(typeof(Unity.Renderer))
    self._disMaterial = G_ResourceManager:loadMaterial("DissolveMat")
    self._material = self._renders[0].sharedMaterials[0]
    
end

function FightActor:setBloodValue(value, maxBlood, isDie)
    self._value = value
    self._value = self._value < 0 and 0 or self._value
    self._maxBlood = maxBlood
    if self._bloodUI then
        self._bloodUI:setValue(value, maxBlood)
    end
    if isDie then
        self:setDie(true)
    end
end

function FightActor:subBlood(hurt)
    self._value = self._value - hurt.value
    self._value = self._value < 0 and 0 or self._value
    if self._bloodUI then
        self._bloodUI:setValue(self._value, self._maxBlood)
    end
    if hurt.die then
        self:setDie(true)
    end
end

function FightActor:setDie(die)
    self._isDie = die
    if die then
        self:_setDieAction()
    end
end

function FightActor:isDie()
    return self._isDie
end

function FightActor:delete()
    GameUtils.destroy(self.gameObject)
    self._bloodUI:close()
end

function FightActor:_setDieAction()
    self._dieAnim = true
    self:_setDissloveMat()
    self:_destroyAppend()
    self._bloodUI.gameObject:SetActive(false)
end

function FightActor:_setDissloveMat()
    self._diePercent = 0
    local material = self._disMaterial
    local len = self._renders.Length
    for i = 0, len - 1, 1 do
        local render = self._renders[i]
        local Length = render.sharedMaterials.Length
        local array = {}
        for j = 1, Length, 1 do
            local tex = render.sharedMaterials[j - 1]:GetTexture("_MainTex")
            local mat = CS.UnityEngine.Material(material)
            mat:CopyPropertiesFromMaterial(material)
            mat.shader = material.shader
            mat:SetTexture("_MainTex", tex)
            mat:SetFloat("_DissolveThreshold", self._diePercent)
            array[j] = mat
        end
        render.receiveShadows = false
        render.shadowCastingMode = 0
        render.sharedMaterials = array
    end
end

function FightActor:update(dt)
    if self._dieAnim then
        self._diePercent = self._diePercent + dt * 0.5
        local len = self._renders.Length
        for i = 0, len - 1, 1 do
            local render = self._renders[i]
            local Length = render.sharedMaterials.Length
            for j = 0, Length - 1, 1 do
                render.sharedMaterials[j]:SetFloat("_DissolveThreshold", self._diePercent)
            end
        end
        if self._diePercent >= 1 then
            self._dieAnim = false
            self._manager:recycleActor(self._id)
            self._diePercent = 0
        end
    end
end

function FightActor:onDestroy()
end

function FightActor:getBloodUI()
    return self._bloodUI
end

function FightActor:playAction(name)
    self._animator:SetTrigger(name .. "Trigger")
end

function FightActor:setMoving(isMove)
    self._animator:SetBool("isMoving", isMove)
end

function FightActor:getAnimationLength(animName)
    local animTime = GameUtils.getAnimationLength(self._animator, animName)
    return animTime
end

function FightActor:setBloodVisible(visible)
    if self.gameObject.active then
        self._bloodUI.gameObject:SetActive(visible)
    end
end

function FightActor:addBuff(id)
    if not self._buffs[id] then
        local config = require("config.buff").get(id)
        assert(config, "can not found cfg in buff by id=" .. id)
        local buff = require("gameLogic.fightSkill.show.BuffInst").new(config, self)
        GameUtils.addChildTo(self.transform, buff.transform)
        buff.transform.localPosition = Vector3.new(0, 1, 0)
        self._buffs[id] = buff
        self:_layoutBuff()
    else
        self._buffs[id]:increaseCount()
    end
end

function FightActor:_destroyAppend()
    for _, buff in pairs(self._buffs) do
        buff:remove()
    end
    for _, sheild in pairs(self._sheilds) do
        sheild:remove()
    end
    self._buffs = {}
    self._sheilds = {}
end

function FightActor:_layoutBuff()
    local startX = -60
    local index = 0
    local width = 20
    for id, buff in pairs(self._buffs) do
        local icon = buff:getIcon()
        local pos = icon.transform.localPosition
        pos.x = startX + index * width
        icon.transform.localPosition = pos
        index = index + 1
    end
end

function FightActor:removeBuff(id)
    local buff = self._buffs[id]
    if buff then
        buff:decreaseCount()
        if buff:getCount() == 0 then
            buff:remove()
            self._buffs[id] = nil
        end
        self:_layoutBuff()
    end
end

function FightActor:addSheild(id)
    if not self._sheilds[id] then
        local config = require("config.sheild").get(id)
        local inst = require("gameLogic.fightSkill.show.SheildInst").new(config, self)
        GameUtils.addChildTo(self.transform, inst.transform)
        inst.transform.localPosition = Vector3.new(0, 1, 0)
        self._sheilds[id] = inst
    else
        self._sheilds[id]:increaseCount()
    end
end

function FightActor:removeSheild(id)
    local sheild = self._sheilds[id]
    if sheild then
        sheild:decreaseCount()
        if sheild:getCount() == 0 then
            sheild:remove()
            self._sheilds[id] = nil
        end
    end
end

return FightActor
